package elephant.servers.gameserver.codec;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import elephant.util.DumpUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.CorruptedFrameException;

/**
 * 
 * @author skydu
 *
 */
public class GameServerDecoder extends ByteToMessageDecoder {
	//
	private static Logger logger=LoggerFactory.getLogger(GameServerDecoder.class);
	//
	private GameServerBodyCodec bodyCodec;
	//
	private static final int MAX_MESSAGE_LENGTH=1024*1024;//1M
	//
	public static final int HEAD_LENGTH=
			4+//total length
			4+//request id
			2+//bodySerializeType
			2;//serviceId length
	//
	public GameServerDecoder(GameServerBodyCodec bodyCodec){
		this.bodyCodec=bodyCodec;
	}
	/**
	 * 
	 */
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        int readable = in.readableBytes();
        if (readable < 4) {
            return;
        }
        in.markReaderIndex();
        int totalLength = in.readInt();
        //
        if(totalLength>MAX_MESSAGE_LENGTH){
        	in.resetReaderIndex();
        	throw new CorruptedFrameException("message length too long "+totalLength+"/"+MAX_MESSAGE_LENGTH);
        }
        if(in.readableBytes()<totalLength-4){
        	in.resetReaderIndex();
        	return;
        }
        int requestId = in.readInt();
        short bodySerializeType= in.readShort();
        short serviceIdLength = in.readShort();
        //
        RequestMessage msg=new RequestMessage();
        msg.requestId=requestId;
        msg.bodySerializeType=bodySerializeType;
        //
        byte[] serviceId=new byte[serviceIdLength];
        in.readBytes(serviceId);
        msg.serviceId=new String(serviceId,"UTF-8");
        //
        byte[] body=new byte[totalLength-HEAD_LENGTH-serviceIdLength];
        in.readBytes(body);
        msg.body=bodyCodec.decode(bodySerializeType, new String(body,"UTF-8"));
        //
        out.add(msg);
        if(logger.isDebugEnabled()){
        	logger.debug("decode totalLength:{} requestId:{},serviceId:{} msg:{}",
        			totalLength,requestId,serviceId,DumpUtil.dump(msg));
        }
    }
}
